1 /* Copyright (C) 2007-2019 Open Information Security Foundation
3 * You can copy, redistribute or modify this Program under the terms of
4 * the GNU General Public License version 2 as published by the Free
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * version 2 along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 * \author Victor Julien <victor@inliniac.net>
25 #include "suricata-common.h"
28 #include "detect-parse.h"
29 #include "detect-engine.h"
30 #include "detect-engine-mpm.h"
31 #include "detect-engine-prefilter.h"
32 #include "detect-engine-content-inspection.h"
33 #include "detect-fast-pattern.h"
34 #include "detect-tcphdr.h"
37 static int DetectTcphdrSetup (DetectEngineCtx
*, Signature
*, const char *);
39 void DetectTcphdrRegisterTests (void);
42 static int g_tcphdr_buffer_id
= 0;
44 static InspectionBuffer
*GetData(DetectEngineThreadCtx
*det_ctx
,
45 const DetectEngineTransforms
*transforms
, Packet
*p
, const int list_id
);
48 * \brief Registration function for tcp.hdr: keyword
50 void DetectTcphdrRegister(void)
52 sigmatch_table
[DETECT_TCPHDR
].name
= "tcp.hdr";
53 sigmatch_table
[DETECT_TCPHDR
].desc
= "sticky buffer to match on the TCP header";
54 sigmatch_table
[DETECT_TCPHDR
].url
= "/rules/header-keywords.html#tcphdr";
55 sigmatch_table
[DETECT_TCPHDR
].Setup
= DetectTcphdrSetup
;
56 sigmatch_table
[DETECT_TCPHDR
].flags
|= SIGMATCH_NOOPT
| SIGMATCH_INFO_STICKY_BUFFER
;
58 sigmatch_table
[DETECT_TCPHDR
].RegisterTests
= DetectTcphdrRegisterTests
;
61 g_tcphdr_buffer_id
= DetectBufferTypeRegister("tcp.hdr");
62 BUG_ON(g_tcphdr_buffer_id
< 0);
64 DetectBufferTypeSupportsPacket("tcp.hdr");
66 DetectPktMpmRegister("tcp.hdr", 2, PrefilterGenericMpmPktRegister
, GetData
);
68 DetectPktInspectEngineRegister("tcp.hdr", GetData
,
69 DetectEngineInspectPktBufferGeneric
);
75 * \brief setup tcp.hdr sticky buffer
77 * \param de_ctx pointer to the Detection Engine Context
78 * \param s pointer to the Current Signature
79 * \param _unused unused
81 * \retval 0 on Success
82 * \retval -1 on Failure
84 static int DetectTcphdrSetup (DetectEngineCtx
*de_ctx
, Signature
*s
, const char *_unused
)
86 if (!(DetectProtoContainsProto(&s
->proto
, IPPROTO_TCP
)))
89 s
->flags
|= SIG_FLAG_REQUIRE_PACKET
;
91 if (DetectBufferSetActiveList(s
, g_tcphdr_buffer_id
) < 0)
97 static InspectionBuffer
*GetData(DetectEngineThreadCtx
*det_ctx
,
98 const DetectEngineTransforms
*transforms
, Packet
*p
, const int list_id
)
102 InspectionBuffer
*buffer
= InspectionBufferGet(det_ctx
, list_id
);
103 if (buffer
->inspect
== NULL
) {
104 if (p
->tcph
== NULL
) {
105 // may happen when DecodeTCPPacket fails
106 // for instance with invalid header length
109 uint32_t hlen
= TCP_GET_HLEN(p
);
110 if (((uint8_t *)p
->tcph
+ (ptrdiff_t)hlen
) >
111 ((uint8_t *)GET_PKT_DATA(p
) + (ptrdiff_t)GET_PKT_LEN(p
)))
113 SCLogDebug("data out of range: %p > %p",
114 ((uint8_t *)p
->tcph
+ (ptrdiff_t)hlen
),
115 ((uint8_t *)GET_PKT_DATA(p
) + (ptrdiff_t)GET_PKT_LEN(p
)));
119 const uint32_t data_len
= hlen
;
120 const uint8_t *data
= (const uint8_t *)p
->tcph
;
122 InspectionBufferSetup(det_ctx
, list_id
, buffer
, data
, data_len
);
123 InspectionBufferApplyTransforms(buffer
, transforms
);
130 #include "tests/detect-tcphdr.c"