suricata
detect-ipaddr.c
Go to the documentation of this file.
1/* Copyright (C) 2022 Open Information Security Foundation
2 *
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
5 * Software Foundation.
6 *
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.
11 *
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
15 * 02110-1301, USA.
16 */
17
18/**
19 * \file
20 *
21 * \author Eric Leblond <el@stamus-networks.com>
22 *
23 * Offer source or destination IP as a sticky buffer.
24 */
25
26#include "suricata-common.h"
27
28#include "decode.h"
29#include "conf.h"
30#include "detect.h"
31#include "detect-parse.h"
32#include "detect-engine.h"
33#include "detect-engine-mpm.h"
35#include "detect-ipaddr.h"
36
37#define KEYWORD_NAME_SRC "ip.src"
38#define KEYWORD_NAME_DST "ip.dst"
39
40static int DetectSrcIPAddrBufferSetup(DetectEngineCtx *, Signature *, const char *);
41static int DetectDestIPAddrBufferSetup(DetectEngineCtx *, Signature *, const char *);
42static InspectionBuffer *GetDataSrc(DetectEngineThreadCtx *det_ctx,
43 const DetectEngineTransforms *transforms, Packet *p, const int list_id);
44static InspectionBuffer *GetDataDst(DetectEngineThreadCtx *det_ctx,
45 const DetectEngineTransforms *transforms, Packet *p, const int list_id);
46
47#ifdef UNITTESTS
48static void DetectIPAddrRegisterTests(void);
49#endif
50static int g_src_ipaddr_buffer_id = 0;
51static int g_dest_ipaddr_buffer_id = 0;
52
54{
56 sigmatch_table[DETECT_IPADDR_SRC].desc = "Sticky buffer for src_ip";
57 sigmatch_table[DETECT_IPADDR_SRC].url = "/rules/ipaddr.html#ip-src";
58 sigmatch_table[DETECT_IPADDR_SRC].Setup = DetectSrcIPAddrBufferSetup;
59#ifdef UNITTESTS
61#endif
62
64
65 g_src_ipaddr_buffer_id = DetectBufferTypeRegister(KEYWORD_NAME_SRC);
66 BUG_ON(g_src_ipaddr_buffer_id < 0);
67
69
71
74
76 sigmatch_table[DETECT_IPADDR_DST].desc = "Sticky buffer for dest_ip";
77 sigmatch_table[DETECT_IPADDR_DST].url = "/rules/ipaddr.html#ip-dst";
78 sigmatch_table[DETECT_IPADDR_DST].Setup = DetectDestIPAddrBufferSetup;
79
81
82 g_dest_ipaddr_buffer_id = DetectBufferTypeRegister(KEYWORD_NAME_DST);
83 BUG_ON(g_dest_ipaddr_buffer_id < 0);
84
86
88
91
92 SCLogDebug("IPAddr detect registered.");
93}
94
95static int DetectSrcIPAddrBufferSetup(DetectEngineCtx *de_ctx, Signature *s, const char *str)
96{
97 /* store list id. Content, pcre, etc will be added to the list at this
98 * id. */
99 s->init_data->list = g_src_ipaddr_buffer_id;
100
101 return 0;
102}
103
104static int DetectDestIPAddrBufferSetup(DetectEngineCtx *de_ctx, Signature *s, const char *str)
105{
106 /* store list id. Content, pcre, etc will be added to the list at this
107 * id. */
108 s->init_data->list = g_dest_ipaddr_buffer_id;
109
110 return 0;
111}
112
113/** \internal
114 * \brief get the data to inspect from the buffer
115 *
116 * \retval buffer or NULL in case of error
117 */
118static InspectionBuffer *GetDataSrc(DetectEngineThreadCtx *det_ctx,
119 const DetectEngineTransforms *transforms, Packet *p, const int list_id)
120{
121 InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id);
122 if (buffer->inspect == NULL) {
123 if (PacketIsIPv4(p)) {
124 /* Suricata stores the IPv4 at the beginning of the field */
125 InspectionBufferSetup(det_ctx, list_id, buffer, p->src.address.address_un_data8, 4);
126 } else if (PacketIsIPv6(p)) {
127 InspectionBufferSetup(det_ctx, list_id, buffer, p->src.address.address_un_data8, 16);
128 } else {
129 return NULL;
130 }
131 InspectionBufferApplyTransforms(det_ctx, buffer, transforms);
132 }
133
134 return buffer;
135}
136
137/** \internal
138 * \brief get the data to inspect from the buffer
139 *
140 * \retval buffer or NULL in case of error
141 */
142static InspectionBuffer *GetDataDst(DetectEngineThreadCtx *det_ctx,
143 const DetectEngineTransforms *transforms, Packet *p, const int list_id)
144{
145 InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id);
146 if (buffer->inspect == NULL) {
147 if (PacketIsIPv4(p)) {
148 /* Suricata stores the IPv4 at the beginning of the field */
149 InspectionBufferSetup(det_ctx, list_id, buffer, p->dst.address.address_un_data8, 4);
150 } else if (PacketIsIPv6(p)) {
151 InspectionBufferSetup(det_ctx, list_id, buffer, p->dst.address.address_un_data8, 16);
152 } else {
153 return NULL;
154 }
155 InspectionBufferApplyTransforms(det_ctx, buffer, transforms);
156 }
157
158 return buffer;
159}
160
161#ifdef UNITTESTS
162#include "tests/detect-ipaddr.c"
163#endif
void InspectionBufferApplyTransforms(DetectEngineThreadCtx *det_ctx, InspectionBuffer *buffer, const DetectEngineTransforms *transforms)
InspectionBuffer * InspectionBufferGet(DetectEngineThreadCtx *det_ctx, const int list_id)
void InspectionBufferSetup(DetectEngineThreadCtx *det_ctx, const int list_id, InspectionBuffer *buffer, const uint8_t *data, const uint32_t data_len)
setup the buffer with our initial data
void DetectPktMpmRegister(const char *name, int priority, int(*PrefilterRegister)(DetectEngineCtx *de_ctx, SigGroupHead *sgh, MpmCtx *mpm_ctx, const DetectBufferMpmRegistry *mpm_reg, int list_id), InspectionBufferGetPktDataPtr GetData)
register a MPM engine
int PrefilterGenericMpmPktRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh, MpmCtx *mpm_ctx, const DetectBufferMpmRegistry *mpm_reg, int list_id)
@ DETECT_IPADDR_SRC
@ DETECT_IPADDR_DST
int DetectEngineInspectPktBufferGeneric(DetectEngineThreadCtx *det_ctx, const DetectEnginePktInspectionEngine *engine, const Signature *s, Packet *p, uint8_t *_alert_flags)
Do the content inspection & validation for a signature.
int DetectBufferTypeRegister(const char *name)
void DetectPktInspectEngineRegister(const char *name, InspectionBufferGetPktDataPtr GetPktData, InspectionBufferPktInspectFunc Callback)
register inspect engine at start up time
void DetectBufferTypeSupportsPacket(const char *name)
#define KEYWORD_NAME_SRC
void DetectIPAddrBufferRegister(void)
#define KEYWORD_NAME_DST
SigTableElmt * sigmatch_table
#define SIGMATCH_NOOPT
Definition detect.h:1651
#define SIGMATCH_INFO_STICKY_BUFFER
Definition detect.h:1676
DetectEngineCtx * de_ctx
uint8_t address_un_data8[16]
Definition decode.h:117
union Address_::@30 address
main detection engine ctx
Definition detect.h:932
Address src
Definition decode.h:505
Address dst
Definition decode.h:506
const char * url
Definition detect.h:1462
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition detect.h:1441
uint16_t flags
Definition detect.h:1450
const char * desc
Definition detect.h:1461
void(* RegisterTests)(void)
Definition detect.h:1448
const char * name
Definition detect.h:1459
Signature container.
Definition detect.h:668
SignatureInitData * init_data
Definition detect.h:747
#define BUG_ON(x)
#define str(s)
void DetectIPAddrRegisterTests(void)
this function registers unit tests for DetectIpv4hdr
#define SCLogDebug(...)
Definition util-debug.h:275