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 
40 static int DetectSrcIPAddrBufferSetup(DetectEngineCtx *, Signature *, const char *);
41 static int DetectDestIPAddrBufferSetup(DetectEngineCtx *, Signature *, const char *);
42 static InspectionBuffer *GetDataSrc(DetectEngineThreadCtx *det_ctx,
43  const DetectEngineTransforms *transforms, Packet *p, const int list_id);
44 static InspectionBuffer *GetDataDst(DetectEngineThreadCtx *det_ctx,
45  const DetectEngineTransforms *transforms, Packet *p, const int list_id);
46 
47 #ifdef UNITTESTS
48 static void DetectIPAddrRegisterTests(void);
49 #endif
50 static int g_src_ipaddr_buffer_id = 0;
51 static 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 
95 static 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 
104 static 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  */
118 static 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(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  */
142 static 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(buffer, transforms);
156  }
157 
158  return buffer;
159 }
160 
161 #ifdef UNITTESTS
162 #include "tests/detect-ipaddr.c"
163 #endif
PrefilterGenericMpmPktRegister
int PrefilterGenericMpmPktRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh, MpmCtx *mpm_ctx, const DetectBufferMpmRegistry *mpm_reg, int list_id)
Definition: detect-engine-prefilter.c:873
SigTableElmt_::url
const char * url
Definition: detect.h:1307
detect-engine.h
SIGMATCH_INFO_STICKY_BUFFER
#define SIGMATCH_INFO_STICKY_BUFFER
Definition: detect.h:1512
SigTableElmt_::desc
const char * desc
Definition: detect.h:1306
sigmatch_table
SigTableElmt * sigmatch_table
Definition: detect-parse.c:127
SigTableElmt_::name
const char * name
Definition: detect.h:1304
DetectEngineTransforms
Definition: detect.h:408
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
DETECT_IPADDR_SRC
@ DETECT_IPADDR_SRC
Definition: detect-engine-register.h:40
DetectPktMpmRegister
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
Definition: detect-engine-mpm.c:541
InspectionBuffer
Definition: detect.h:373
Address_::address
union Address_::@26 address
SigTableElmt_::flags
uint16_t flags
Definition: detect.h:1298
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:841
detect-ipaddr.c
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1289
detect-engine-prefilter.h
InspectionBufferGet
InspectionBuffer * InspectionBufferGet(DetectEngineThreadCtx *det_ctx, const int list_id)
Definition: detect-engine.c:1500
DetectBufferTypeSupportsPacket
void DetectBufferTypeSupportsPacket(const char *name)
Definition: detect-engine.c:1063
KEYWORD_NAME_DST
#define KEYWORD_NAME_DST
Definition: detect-ipaddr.c:38
decode.h
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:17
DetectEngineThreadCtx_
Definition: detect.h:1093
DetectPktInspectEngineRegister
void DetectPktInspectEngineRegister(const char *name, InspectionBufferGetPktDataPtr GetPktData, InspectionBufferPktInspectFunc Callback)
register inspect engine at start up time
Definition: detect-engine.c:130
SignatureInitData_::list
int list
Definition: detect.h:570
detect-engine-mpm.h
detect.h
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:300
Packet_
Definition: decode.h:473
KEYWORD_NAME_SRC
#define KEYWORD_NAME_SRC
Definition: detect-ipaddr.c:37
conf.h
Address_::address_un_data8
uint8_t address_un_data8[16]
Definition: decode.h:113
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:670
DetectIPAddrRegisterTests
void DetectIPAddrRegisterTests(void)
this function registers unit tests for DetectIpv4hdr
Definition: detect-ipaddr.c:44
DetectBufferTypeRegister
int DetectBufferTypeRegister(const char *name)
Definition: detect-engine.c:1029
suricata-common.h
InspectionBufferApplyTransforms
void InspectionBufferApplyTransforms(InspectionBuffer *buffer, const DetectEngineTransforms *transforms)
Definition: detect-engine.c:1711
InspectionBuffer::inspect
const uint8_t * inspect
Definition: detect.h:374
str
#define str(s)
Definition: suricata-common.h:291
InspectionBufferSetup
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
Definition: detect-engine.c:1595
detect-parse.h
Signature_
Signature container.
Definition: detect.h:601
DetectIPAddrBufferRegister
void DetectIPAddrBufferRegister(void)
Definition: detect-ipaddr.c:53
Packet_::dst
Address dst
Definition: decode.h:478
SIGMATCH_NOOPT
#define SIGMATCH_NOOPT
Definition: detect.h:1488
detect-ipaddr.h
DetectEngineInspectPktBufferGeneric
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.
Definition: detect-engine.c:2250
Packet_::src
Address src
Definition: decode.h:477
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1296
DETECT_IPADDR_DST
@ DETECT_IPADDR_DST
Definition: detect-engine-register.h:41