1 /* Copyright (C) 2020 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 Jeff Lucovsky <jeff@lucovsky.org>
25 #include "suricata-common.h"
28 #include "detect-engine.h"
29 #include "detect-engine-mpm.h"
30 #include "detect-icmpv4hdr.h"
33 static int DetectIcmpv4HdrSetup(DetectEngineCtx
*, Signature
*, const char *);
35 void DetectIcmpv4HdrRegisterTests(void);
38 static int g_icmpv4hdr_buffer_id
= 0;
40 static InspectionBuffer
*GetData(DetectEngineThreadCtx
*det_ctx
,
41 const DetectEngineTransforms
*transforms
, Packet
*p
, const int list_id
);
44 * \brief Registration function for icmpv4.hdr: keyword
46 void DetectIcmpv4HdrRegister(void)
48 sigmatch_table
[DETECT_ICMPV4HDR
].name
= "icmpv4.hdr";
49 sigmatch_table
[DETECT_ICMPV4HDR
].desc
= "sticky buffer to match on the ICMP v4 header";
50 sigmatch_table
[DETECT_ICMPV4HDR
].url
= "/rules/header-keywords.html#icmpv4-hdr";
51 sigmatch_table
[DETECT_ICMPV4HDR
].Setup
= DetectIcmpv4HdrSetup
;
52 sigmatch_table
[DETECT_ICMPV4HDR
].flags
|= SIGMATCH_NOOPT
| SIGMATCH_INFO_STICKY_BUFFER
;
54 sigmatch_table
[DETECT_ICMPV4HDR
].RegisterTests
= DetectIcmpv4HdrRegisterTests
;
57 g_icmpv4hdr_buffer_id
= DetectBufferTypeRegister("icmpv4.hdr");
58 BUG_ON(g_icmpv4hdr_buffer_id
< 0);
60 DetectBufferTypeSupportsPacket("icmpv4.hdr");
62 DetectPktMpmRegister("icmpv4.hdr", 2, PrefilterGenericMpmPktRegister
, GetData
);
64 DetectPktInspectEngineRegister("icmpv4.hdr", GetData
, DetectEngineInspectPktBufferGeneric
);
70 * \brief setup icmpv4.hdr sticky buffer
72 * \param de_ctx pointer to the Detection Engine Context
73 * \param s pointer to the Current Signature
74 * \param _unused unused
76 * \retval 0 on Success
77 * \retval -1 on Failure
79 static int DetectIcmpv4HdrSetup(DetectEngineCtx
*de_ctx
, Signature
*s
, const char *_unused
)
81 if (!(DetectProtoContainsProto(&s
->proto
, IPPROTO_ICMP
)))
84 s
->proto
.flags
|= DETECT_PROTO_IPV4
;
85 s
->flags
|= SIG_FLAG_REQUIRE_PACKET
;
87 if (DetectBufferSetActiveList(s
, g_icmpv4hdr_buffer_id
) < 0)
93 static InspectionBuffer
*GetData(DetectEngineThreadCtx
*det_ctx
,
94 const DetectEngineTransforms
*transforms
, Packet
*p
, const int list_id
)
98 if (p
->icmpv4h
== NULL
) {
99 SCReturnPtr(NULL
, "InspectionBuffer");
102 InspectionBuffer
*buffer
= InspectionBufferGet(det_ctx
, list_id
);
103 if (buffer
->inspect
== NULL
) {
104 uint16_t hlen
= ICMPV4_GET_HLEN_ICMPV4H(p
);
105 if (((uint8_t *)p
->icmpv4h
+ (ptrdiff_t)hlen
) >
106 ((uint8_t *)GET_PKT_DATA(p
) + (ptrdiff_t)GET_PKT_LEN(p
))) {
107 SCLogDebug("data out of range: %p > %p", ((uint8_t *)p
->icmpv4h
+ (ptrdiff_t)hlen
),
108 ((uint8_t *)GET_PKT_DATA(p
) + (ptrdiff_t)GET_PKT_LEN(p
)));
109 SCReturnPtr(NULL
, "InspectionBuffer");
112 const uint32_t data_len
= hlen
;
113 const uint8_t *data
= (const uint8_t *)p
->icmpv4h
;
115 InspectionBufferSetup(det_ctx
, list_id
, buffer
, data
, data_len
);
116 InspectionBufferApplyTransforms(buffer
, transforms
);
119 SCReturnPtr(buffer
, "InspectionBuffer");
123 #include "tests/detect-icmpv4hdr.c"